/**
 * HappyFarm API v2
 *
 * Author: Cong Liu
 * Date: 03/07/2009
 *
 **/

(function(){with(HappyFarm.util){

HappyFarm.api = {
    _get: function(data, complete) {
        return this._base('GET', data, complete);
    },
    _post: function(data, complete) {
        return this._base('POST', data, complete);
    },
    _base: function(method, data, complete){
        var sTime = HappyFarm.GlobalData.ServerTime;
        data = extend({}, data, {
            farmTime: sTime,
            farmKey: hex_md5( sTime + HappyFarm.GlobalData.EncodeKey ),
            inuId: undefined
        });
        var get, post;
        [get, post] = encodeData(data);

        return request({
            url: getPref('api_url', '')+'?'+get,
            data: post,
            method: method,
            timeout: 5000,
            complete: function(status, xhr){
                if(status == 'success') {
                    try{
                        var json = safelyEvalJSON(xhr.responseText, getPref('homepage_url', ''));
                        if(json.hasOwnProperty('code') && json.code == 0) {
                            json.errorType = json.errorContent = 'apierror';
                        }
                    } catch (e) {
                        json = {errorType: 'parsererror', errorContent: 'parsererror'};
                    }
                } else {
                    json = {errorType: 'networkerror' , errorContent: status};
                }
                complete(json);
            }
        });

        function safelyEvalJSON(json, url){
            var s = Components.utils.Sandbox(url);
            return Components.utils.evalInSandbox('('+json+')', s);
        }

        function encodeData(data) {
            var get = [], post = {};
            for(var p in data) {
                if(p == 'mod' || p == 'act' || p == 'flag' || p == 'farmKey' || p == 'farmTime' || p == 'inuId')
                    get.push(p+'='+(data[p]!==undefined?encodeURIComponent(data[p]):''));
                else
                    post[p] = data[p];
            }
            return [get.join('&'), post];
        }

    },
    /**
     * HFAPI: CROPS
     *      Load HappyFarm configurations and crop infomation
     *
     * @return XML
     *
     **/
    crops: function(complete){
        var xhr = request({
            url: getPref('ini_url', ''),
            timeout: 5000,
            complete: function(status, xhr) {
                if(status == 'success') {
                    //Due to a bug, happyfarm server returns an invalid xml.
                    //Replacing & with the entity &amp; could resolve the problem
                    var responseText = (xhr.responseText || '')
                                        .replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, "") // bug 336551
                                        .replace(/&/, '&amp;');
                    try{
                        var doc = new XML(responseText);
                    } catch (e) {
                        var doc = <parsererror>
                            <errorType>parsererror</errorType>
                            <errorContent>parsererror</errorContent>
                        </parsererror>;
                    }
                } else {
                    var doc = <parsererror>
                                <errorType>{status}</errorType>
                                <errorContent>{status}</errorContent>
                            </parsererror>;
                }
                log('DEBUG', doc);
                HappyFarm.GlobalData.setCropsResult(doc);
                if(complete) complete(doc);
            }
        });
    },
    /**
     * HFAPI: USER/RUN
     *      Get basic user information
     * 
     * @param int ownerId   User ID (optional)
     * @param int flag      Partial flag. If set, return partial user information (without weather etc). Otherwise, return full user information.
     * @return json
     *  {
     *      a: int,
     *      b: int,
     *      c: int,
     *      exp: int, //Experience
     *      dog: {
     *          dogId: int, //Has dog
     *          isHungry: bool, //Dog is hungry
     *      },
     *      farmStatus: [
     *          {
     *              a: int,     //cId:          Crop Id
     *              b: int,     //cropStatus:   Crop status
     *              c: int,     //oldweed:      Old weed status
     *              d: int,     //oldpest:      Old pest status
     *              e: int,     //oldhumidity:  Old humidity status
     *              f: int,     //weed:         How many weeds?
     *              g: int,     //pest:         How many pests?
     *              h: int,     //humidity:     Is humidity?
     *              i: int,     //health:       Health (max health is 100)
     *              j: int,     //harvestTimes: How many times has the crop been harvested?
     *              k: int,     //output:       How many fruits does it produce?
     *              l: int,     //min:          Minimal output
     *              m: int,     //leavings:     How many fruits is left?
     *              n: [],      //thief:        List of thieves
     *              o: int,     //fertilize?:   True if o = step+1.
     *              p: [],      //action:       List of actions
     *              q: int,     //plantTime:    Plant time. For multiple season crops, the plant time is the "corresponding plant time".
     *              r: int,     //updateTime:   Update time
     *              s: int,     //pId:          
     *              t: int,     //nPh:          Current PH of big pest
     *              u: int      //mPh:          Maximal PH of big pest
     *          }
     *      ]
     *  }
     *  
     **/
    run: function(ownerId, flag, complete){
        this._post({mod:'user', act:'run', ownerId: ownerId, flag: flag}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setRunResult(ownerId, data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: FRIEND
     *
     * @return json
     **/
    friend: function(complete){
        this._post({mod:'friend'}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setFriendResult(data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: REPERTORY/GETSEEDINFO
     *
     * @return json
     **/
    seeds: function(complete){
        this._get({mod:'repertory', act:'getSeedInfo'}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setSeedsResult(data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: FARMLANDSTATUS/WATER
     *
     * @return json
     **/
    water: function(ownerId, place, complete){
        this._post({mod:'farmlandstatus', act:'water', ownerId: ownerId, place: place}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setWaterResult(ownerId, place, data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: FARMLANDSTATUS/CLEARWEED
     *
     * @return json
     **/
    clearWeed: function(ownerId, place, complete){
        this._post({mod:'farmlandstatus', act:'clearWeed', ownerId: ownerId, place: place}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setClearWeedResult(ownerId, place, data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: FARMLANDSTATUS/SPRAYING
     *
     * @return json
     **/
    spraying: function(ownerId, place, complete){
        this._post({mod:'farmlandstatus', act:'spraying', ownerId: ownerId, place: place}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setSprayingResult(ownerId, place, data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: FARMLANDSTATUS/HARVEST
     *
     * @return json
     **/
    harvest: function(ownerId, place, complete){
        this._post({mod:'farmlandstatus', act:'harvest', ownerId: ownerId, place: place}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setHarvestResult(ownerId, place, data);
            if(complete) complete(data);
        });
    },
    /**
     * HFAPI: FARMLANDSTATUS/PLANTING
     *
     * @return json
     **/
    planting: function(place, cId, complete){
        this._post({mod:'farmlandstatus', act:'planting', ownerId: HappyFarm.GlobalData.uId, place: place, cId: cId}, function(data){
            log('DEBUG', data);
            HappyFarm.GlobalData.setPlantingResult(place, cId, data);
            if(complete) complete(data);
        });
    },
};

}})();
